package com.service.business.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.service.business.base.dto.LoginUserSession;
import com.service.core.exception.CommonException;
import com.service.dao.enums.CommonStatusEnums;
import com.service.dao.enums.MemberAddressEnum;
import com.service.business.member.controller.rep.MemberAddressRep;
import com.service.business.member.controller.req.MemberAddressCreateReq;
import com.service.business.member.controller.req.MemberAddressUpdateReq;
import com.service.business.member.service.MemberAddressService;
import com.service.dao.mapper.MemberAddressMapper;
import com.service.dao.model.MemberAddress;
import com.service.business.support.SessionUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Service("memberAddressService")
public class MemberAddressServiceImpl extends ServiceImpl<MemberAddressMapper, MemberAddress> implements MemberAddressService {
    @Autowired
    private SessionUtil sessionUtil;

    @Override
    public MemberAddressRep getMemberDefaultAddress(Integer memberId) {

        MemberAddress memberAddress = getOne(new QueryWrapper<MemberAddress>().lambda()
                .eq(MemberAddress::getDefaultUse, MemberAddressEnum.DefaultUse.DEFAULT.getCode())
                .eq(MemberAddress::getAddressStatus, CommonStatusEnums.ACTIVE.getCode())
                .eq(MemberAddress::getMemberId, sessionUtil.getUser().getUserId()).last(" limit 1"));

        if (ObjectUtils.isEmpty(memberAddress)) {
            memberAddress = getOne(new QueryWrapper<MemberAddress>().lambda()
                    .eq(MemberAddress::getAddressStatus, CommonStatusEnums.ACTIVE.getCode())
                    .eq(MemberAddress::getMemberId, sessionUtil.getUser().getUserId()).last(" limit 1"));

            if (!ObjectUtils.isEmpty(memberAddress)) {
                updateById(MemberAddress.builder().id(memberAddress.getId())
                        .defaultUse(MemberAddressEnum.DefaultUse.DEFAULT.getCode()).build());
            }

        }

        return ObjectUtils.isEmpty(memberAddress) ? null : ModelMapperUtil.getStrictModelMapper().map(memberAddress, MemberAddressRep.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addMemberAddress(Integer memberId, MemberAddressCreateReq memberAddressCreateReq) {
        MemberAddress memberAddress = ModelMapperUtil.getStrictModelMapper().map(memberAddressCreateReq, MemberAddress.class);
        memberAddress.setMemberId(memberId);
        if (!ObjectUtils.isEmpty(list(new QueryWrapper<MemberAddress>().lambda()
                .eq(MemberAddress::getMemberId, memberAddress.getMemberId())
                .eq(MemberAddress::getAreaCode, memberAddress.getAreaCode())
                .eq(MemberAddress::getAddress, memberAddress.getAddress())))) {
            throw new CommonException("已存在此地址，请勿重复添加", "member_business_address_has_exist");
        }

        if (ObjectUtils.nullSafeEquals(memberAddress.getDefaultUse(), MemberAddressEnum.DefaultUse.DEFAULT.getCode())) {
            updateDefaultUse2NotDefault(memberId);
        }
        memberAddress.setAddressStatus(CommonStatusEnums.ACTIVE.getCode());
        memberAddress.setCreateTime(new Date());
        save(memberAddress);
        return memberAddress.getMemberId();
    }

    @Override
    public List<MemberAddressRep> getMemberAddress(Integer memberId) {
        List<MemberAddress> memberAddressList = list(new QueryWrapper<MemberAddress>().lambda()
                .eq(MemberAddress::getMemberId, memberId)
                .eq(MemberAddress::getAddressStatus, CommonStatusEnums.ACTIVE.getCode()));
        return memberAddressList.stream().map(item -> ModelMapperUtil.getStrictModelMapper().map(item, MemberAddressRep.class)).collect(Collectors.toList());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateAddress(Integer addressId, MemberAddressUpdateReq memberAddressUpdateReq) {
        MemberAddress memberAddress = getById(addressId);
        if (ObjectUtils.isEmpty(memberAddress)) {
            log.error("更新地址<addressId:{}>操作失败", addressId);
            throw new CommonException("不存在此地址", "member_business_address_not_exist");
        }
        if (ObjectUtils.nullSafeEquals(memberAddress.getDefaultUse(), MemberAddressEnum.DefaultUse.DEFAULT.getCode())) {
            updateDefaultUse2NotDefault(sessionUtil.getUser().getUserId());
        }
        BeanUtils.copyProperties(memberAddressUpdateReq, memberAddress);
        updateById(memberAddress);
        return addressId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delete(Integer addressId) {
        MemberAddress memberAddress = getById(addressId);
        if (ObjectUtils.isEmpty(memberAddress)) {
            log.error("删除地址<addressId:{}>操作失败", addressId);
            throw new CommonException("不存在此地址", "member_business_address_not_exist");
        }
        memberAddress = new MemberAddress();
        memberAddress.setId(addressId);
        memberAddress.setAddressStatus(CommonStatusEnums.INVALID.getCode());
        return updateById(memberAddress) ? 1 : 0;
    }

    @Override
    public MemberAddressRep getAddressDetail(Integer addressId) {
        MemberAddress memberAddress = getById(addressId);
        MemberAddressRep memberAddressRep = ModelMapperUtil.getStrictModelMapper().map(memberAddress, MemberAddressRep.class);
        return memberAddressRep;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeDefaultAddress(Integer addressId) {
        if (ObjectUtils.isEmpty(getById(addressId))) {
            log.error("更新默认地址<addressId:{}>失败,无此地址", addressId);
            throw new CommonException("无此地址", "member_business_address_not_exist");
        }
        LoginUserSession session = sessionUtil.getUser();
        updateDefaultUse2NotDefault(session.getUserId());

        MemberAddress memberAddress = new MemberAddress();
        memberAddress.setId(addressId);
        memberAddress.setDefaultUse(MemberAddressEnum.DefaultUse.DEFAULT.getCode());
        updateById(memberAddress);
    }

    private void updateDefaultUse2NotDefault(Integer memberId) {
        MemberAddress memberAddress = new MemberAddress();
        memberAddress.setDefaultUse(MemberAddressEnum.DefaultUse.NOT_DEFAULT.getCode());
        update(memberAddress, new QueryWrapper<MemberAddress>().lambda()
                .eq(MemberAddress::getAddressStatus, MemberAddressEnum.DefaultUse.DEFAULT.getCode())
                .eq(MemberAddress::getMemberId, memberId));
    }

}
